package com.core.cloudbusiness.system.depart.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.core.cloudbusiness.system.depart.mapper.CloudSystemDepartMapper;
import com.core.cloudbusiness.system.depart.service.CloudSystemDepartService;
import com.core.cloudbusiness.tool.CommonRequestContext;
import com.core.cloudcommon.CommonCustomException;
import com.core.cloudcommon.CommonInteger;
import com.core.cloudcommon.redis.service.CloudRedisTemplateService;
import com.core.cloudcommon.redis.vo.CloudRedisVO;
import com.core.cloudcommon.utils.IdUtils;
import com.core.cloundbusinessapi.system.depart.dto.CloudSystemDepartDTO;
import com.core.cloundbusinessapi.system.depart.dto.CloudSystemDepartQueryDTO;
import com.core.cloundbusinessapi.system.depart.enums.CloudSystemDepartResultCode;
import com.core.cloundbusinessapi.system.depart.vo.CloudSystemDepartVO;
import com.core.cloundbusinessapi.system.user.dto.CloudSystemUserDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author =====Lqj=====
 * @className CloudSystemDepartServiceImpl
 * @description
 * @create 2024/11/29 14:12
 **/
@Slf4j
@Service
public class CloudSystemDepartServiceImpl implements CloudSystemDepartService {


    @Autowired
    private CloudSystemDepartMapper cloudSystemDepartMapper;

    @Autowired
    private CloudRedisTemplateService cloudRedisTemplateService;

    private Snowflake snowflake = IdUtil.createSnowflake(3L, 3L);


    private final String departKey = "sysDepartKey001";
    private final String departOrderKey = "depart01";


    @Override
    public List<CloudSystemDepartQueryDTO> query(CloudSystemDepartVO cloudSystemDepartVO) {
        if (Objects.isNull(cloudSystemDepartVO)) {
            throw new CommonCustomException(CloudSystemDepartResultCode.CODE700001.getCode(), CloudSystemDepartResultCode.CODE700001.getMsg());
        }
        String cacheDepart = (String) cloudRedisTemplateService.get(new CloudRedisVO(departKey));
        List<CloudSystemDepartQueryDTO> list = new ArrayList<>(CommonInteger.Integer16);
        if (cloudSystemDepartVO.judge()) {
            if (cacheDepart == null) {
                cloudSystemDepartMapper.queryDepartAllMapper().forEach(aa -> {
                    CloudSystemDepartQueryDTO cloudSystemDepartQuery = new CloudSystemDepartQueryDTO();
                    BeanUtils.copyProperties(aa, cloudSystemDepartQuery);
                    list.add(cloudSystemDepartQuery);
                });
                cloudRedisTemplateService.set(new CloudRedisVO(departKey, JSON.toJSONString(list)));
            } else {
                list.addAll(JSON.parseArray(cacheDepart, CloudSystemDepartQueryDTO.class));
            }
            Map<Long, List<CloudSystemDepartQueryDTO>> collect = list.stream().collect(Collectors.groupingBy(CloudSystemDepartDTO::getParentId));
            return list.stream()
                    .filter(department -> department.getParentId() == 0L)
                    .map(department -> buildTree(department, collect))
                    .collect(Collectors.toList());
        }
        CloudSystemDepartDTO cloudSystemDepartDTO = cloudSystemDepartMapper.queryMapper(cloudSystemDepartVO);
        CloudSystemDepartQueryDTO cloudSystemDepartQuery = new CloudSystemDepartQueryDTO();
        BeanUtils.copyProperties(cloudSystemDepartDTO, cloudSystemDepartQuery);
        list.add(cloudSystemDepartQuery);
        return list;
    }

    @Override
    public CloudSystemDepartDTO add(CloudSystemDepartVO cloudSystemDepartVO) {
        if (Objects.isNull(cloudSystemDepartVO)) {
            throw new CommonCustomException(CloudSystemDepartResultCode.CODE700002.getCode(), CloudSystemDepartResultCode.CODE700002.getMsg());
        }
        CloudSystemUserDTO user = CommonRequestContext.getCurrentUser();
        CloudSystemDepartVO systemDepart = new CloudSystemDepartVO();
        systemDepart.setDepartCode(cloudSystemDepartVO.getDepartCode() + "01");
        if (cloudSystemDepartVO.getDepartCode() == null) {
            cloudSystemDepartVO.setDepartCode("01");
        }
        CloudSystemDepartDTO cloudSystemDepart = cloudSystemDepartMapper.queryMapper(systemDepart);
        CloudSystemDepartDTO cloudSystemDepartDTO = new CloudSystemDepartDTO();
        cloudSystemDepartDTO.setDepartName(cloudSystemDepartVO.getDepartName());
        if (cloudSystemDepartVO.getParentId() == null) {
            cloudSystemDepartDTO.setParentId(0L);
        } else {
            cloudSystemDepartDTO.setParentId(cloudSystemDepartVO.getParentId());
        }
        cloudSystemDepartDTO.setId(IdUtils.generateSystemDepartId());
        Integer cacheOrder = (Integer) cloudRedisTemplateService.get(new CloudRedisVO(departOrderKey));
        if (cacheOrder == null) {
            Integer dbOrder = cloudSystemDepartMapper.queryDepartOrderMapper();
            Integer newOrder = dbOrder + CommonInteger.Integer1;
            cloudRedisTemplateService.set(new CloudRedisVO(departOrderKey, newOrder, 86400L));
            cloudSystemDepartDTO.setDepartOrder(newOrder);
        } else {
            Integer newOrder = cacheOrder + CommonInteger.Integer1;
            cloudRedisTemplateService.set(new CloudRedisVO(departOrderKey, newOrder, 86400L));
            cloudSystemDepartDTO.setDepartOrder(newOrder);
        }

        cloudSystemDepartDTO.setDepartCode(systemDepart.getDepartCode());
        if (Objects.nonNull(cloudSystemDepart)) {
            String departCode = generateDeptCode(cloudSystemDepart.getDepartCode());
            cloudSystemDepartDTO.setDepartCode(departCode);
        } else {
            cloudSystemDepartDTO.setDepartCode(cloudSystemDepartVO.getDepartCode() + "01");
        }
        cloudSystemDepartDTO.setCreateBy(user.getUserName());
        cloudSystemDepartDTO.setCreateTime(new Date());
        cloudSystemDepartDTO.setUpdateTime(new Date());
        cloudSystemDepartMapper.insert(cloudSystemDepartDTO);
        cloudRedisTemplateService.del(departKey);
        return cloudSystemDepartDTO;
    }

    /**
     * 生成新的部门编码
     *
     * @param maxChildCode
     * @return
     */
    public static String generateDeptCode(String maxChildCode) {
        // 假设最大子级编码最后一部分是递增的
        // 保留前缀
        String prefix = maxChildCode.substring(0, maxChildCode.length() - 1);
        // 获取最后一位
        String lastPart = maxChildCode.substring(maxChildCode.length() - 1);
        // 将最后一位转换为数字
        int lastCode = Integer.parseInt(lastPart);
        // 递增1
        lastCode++;
        // 保证递增后仍然是两位数
        String newLastPart = String.format("%0" + lastPart.length() + "d", lastCode);
        // 拼接新的编码
        return prefix + newLastPart;
    }


    /**
     * 递归构造部门结构
     *
     * @param parent
     * @param departmentMap
     * @return
     */
    private CloudSystemDepartQueryDTO buildTree(CloudSystemDepartQueryDTO parent, Map<Long, List<CloudSystemDepartQueryDTO>> departmentMap) {
        List<CloudSystemDepartQueryDTO> children = departmentMap.getOrDefault(parent.getId(), Collections.emptyList());
        for (CloudSystemDepartQueryDTO child : children) {
            buildTree(child, departmentMap);
            parent.addChild(child); // 递归构建子树
        }// 将子节点加入父节点
        return parent;
    }
}
